<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
        "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <link href="../Styles/style.css" rel="stylesheet" type="text/css"/>


</head>

<body>
<div class="article-body">

    <div class="article-intro" id="content">

        <h1>Python3 错误和异常</h1>
        <p>作为Python初学者，在刚学习Python编程时，经常会看到一些报错信息，在前面我们没有提及，这章节我们会专门介绍。</p>
        <p>Python有两种错误很容易辨认：语法错误和异常。</p>
        <h2>语法错误</h2>
        <p>Python 的语法错误或者称之为解析错，是初学者经常碰到的，如下实例</p>
        <pre class="prettyprint prettyprinted" style=""><span class="pun">&gt;&gt;&gt;</span><span
                class="pln"> </span><span class="kwd">while</span><span class="pln"> </span><span
                class="kwd">True</span><span class="pln"> </span><span class="kwd">print</span><span
                class="pun">(</span><span class="str">'Hello world'</span><span class="pun">)</span><span class="pln">
  </span><span class="typ">File</span><span class="pln"> </span><span class="str">"&lt;stdin&gt;"</span><span
                class="pun">,</span><span class="pln"> line </span><span class="lit">1</span><span
                class="pun">,</span><span class="pln"> </span><span class="kwd">in</span><span class="pln"> </span><span
                class="pun">?</span><span class="pln">
    </span><span class="kwd">while</span><span class="pln"> </span><span class="kwd">True</span><span
                class="pln"> </span><span class="kwd">print</span><span class="pun">(</span><span class="str">'Hello world'</span><span
                class="pun">)</span><span class="pln">
                   </span><span class="pun">^</span><span class="pln">
</span><span class="typ">SyntaxError</span><span class="pun">:</span><span class="pln"> invalid syntax</span></pre>
        <p>这个例子中，函数 print() 被检查到有错误，是它前面缺少了一个冒号（:）。</p>
        <p>
            语法分析器指出了出错的一行，并且在最先找到的错误的位置标记了一个小小的箭头。</p>
        <h2>异常</h2>
        <p>即便Python程序的语法是正确的，在运行它的时候，也有可能发生错误。运行期检测到的错误被称为异常。</p>
        <p>大多数的异常都不会被程序处理，都以错误信息的形式展现在这里:</p>
        <pre class="prettyprint prettyprinted" style=""><span class="pun">&gt;&gt;&gt;</span><span
                class="pln"> </span><span class="lit">10</span><span class="pln"> </span><span class="pun">*</span><span
                class="pln"> </span><span class="pun">(</span><span class="lit">1</span><span class="pun">/</span><span
                class="lit">0</span><span class="pun">)</span><span class="pln">
</span><span class="typ">Traceback</span><span class="pln"> </span><span class="pun">(</span><span class="pln">most recent call </span><span
                class="kwd">last</span><span class="pun">):</span><span class="pln">
  </span><span class="typ">File</span><span class="pln"> </span><span class="str">"&lt;stdin&gt;"</span><span
                class="pun">,</span><span class="pln"> line </span><span class="lit">1</span><span
                class="pun">,</span><span class="pln"> </span><span class="kwd">in</span><span class="pln"> </span><span
                class="pun">?</span><span class="pln">
</span><span class="typ">ZeroDivisionError</span><span class="pun">:</span><span class="pln"> division </span><span
                class="kwd">by</span><span class="pln"> zero
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> </span><span class="lit">4</span><span
                class="pln"> </span><span class="pun">+</span><span class="pln"> spam</span><span
                class="pun">*</span><span class="lit">3</span><span class="pln">
</span><span class="typ">Traceback</span><span class="pln"> </span><span class="pun">(</span><span class="pln">most recent call </span><span
                class="kwd">last</span><span class="pun">):</span><span class="pln">
  </span><span class="typ">File</span><span class="pln"> </span><span class="str">"&lt;stdin&gt;"</span><span
                class="pun">,</span><span class="pln"> line </span><span class="lit">1</span><span
                class="pun">,</span><span class="pln"> </span><span class="kwd">in</span><span class="pln"> </span><span
                class="pun">?</span><span class="pln">
</span><span class="typ">NameError</span><span class="pun">:</span><span class="pln"> name </span><span class="str">'spam'</span><span
                class="pln"> </span><span class="kwd">is</span><span class="pln"> </span><span
                class="kwd">not</span><span class="pln"> </span><span class="kwd">defined</span><span class="pln">
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> </span><span class="str">'2'</span><span
                class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="lit">2</span><span
                class="pln">
</span><span class="typ">Traceback</span><span class="pln"> </span><span class="pun">(</span><span class="pln">most recent call </span><span
                class="kwd">last</span><span class="pun">):</span><span class="pln">
  </span><span class="typ">File</span><span class="pln"> </span><span class="str">"&lt;stdin&gt;"</span><span
                class="pun">,</span><span class="pln"> line </span><span class="lit">1</span><span
                class="pun">,</span><span class="pln"> </span><span class="kwd">in</span><span class="pln"> </span><span
                class="pun">?</span><span class="pln">
</span><span class="typ">TypeError</span><span class="pun">:</span><span class="pln"> </span><span
                class="typ">Can</span><span class="str">'t convert '</span><span class="kwd">int</span><span
                class="str">' object to str implicitly</span></pre>
        <p>异常以不同的类型出现，这些类型都作为信息的一部分打印出来: 例子中的类型有 ZeroDivisionError，NameError 和 TypeError。
        </p>
        <p>错误信息的前面部分显示了异常发生的上下文，并以调用栈的形式显示具体信息。
        </p>
        <h2>异常处理</h2>
        <p>以下例子中，让用户输入一个合法的整数，但是允许用户中断这个程序（使用 Control-C 或者操作系统提供的方法）。用户中断的信息会引发一个 KeyboardInterrupt 异常。
        </p>
        <pre class="prettyprint prettyprinted" style=""><span class="pun">&gt;&gt;&gt;</span><span
                class="pln"> </span><span class="kwd">while</span><span class="pln"> </span><span
                class="kwd">True</span><span class="pun">:</span><span class="pln">
        </span><span class="kwd">try</span><span class="pun">:</span><span class="pln">
            x </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">int</span><span
                class="pun">(</span><span class="pln">input</span><span class="pun">(</span><span class="str">"Please enter a number: "</span><span
                class="pun">))</span><span class="pln">
            </span><span class="kwd">break</span><span class="pln">
        </span><span class="kwd">except</span><span class="pln"> </span><span class="typ">ValueError</span><span
                class="pun">:</span><span class="pln">
            </span><span class="kwd">print</span><span class="pun">(</span><span class="str">"Oops!  That was no valid number.  Try again   "</span><span
                class="pun">)</span><span class="pln">
   </span></pre>
        <p>try语句按照如下方式工作；</p>
        <ul>
            <li>首先，执行try子句（在关键字try和关键字except之间的语句）</li>
            <li>如果没有异常发生，忽略except子句，try子句执行后结束。</li>
            <li>如果在执行try子句的过程中发生了异常，那么try子句余下的部分将被忽略。如果异常的类型和 except 之后的名称相符，那么对应的except子句将被执行。最后执行 try 语句之后的代码。</li>
            <li>如果一个异常没有与任何的except匹配，那么这个异常将会传递给上层的try中。</li>

        </ul>
        <p>一个 try 语句可能包含多个except子句，分别来处理不同的特定的异常。最多只有一个分支会被执行。</p>
        <p>处理程序将只针对对应的try子句中的异常进行处理，而不是其他的 try 的处理程序中的异常。</p>
        <p>一个except子句可以同时处理多个异常，这些异常将被放在一个括号里成为一个元组，例如:
        </p>
        <pre class="prettyprint prettyprinted" style=""><span class="pln">    </span><span
                class="kwd">except</span><span class="pln"> </span><span class="pun">(</span><span class="typ">RuntimeError</span><span
                class="pun">,</span><span class="pln"> </span><span class="typ">TypeError</span><span
                class="pun">,</span><span class="pln"> </span><span class="typ">NameError</span><span
                class="pun">):</span><span class="pln">
        </span><span class="kwd">pass</span></pre>
        <p>最后一个except子句可以忽略异常的名称，它将被当作通配符使用。你可以使用这种方法打印一个错误信息，然后再次把异常抛出。</p>
        <pre class="prettyprint prettyprinted" style=""><span class="kwd">import</span><span class="pln"> sys

</span><span class="kwd">try</span><span class="pun">:</span><span class="pln">
    f </span><span class="pun">=</span><span class="pln"> open</span><span class="pun">(</span><span class="str">'myfile.txt'</span><span
                class="pun">)</span><span class="pln">
    s </span><span class="pun">=</span><span class="pln"> f</span><span class="pun">.</span><span
                class="pln">readline</span><span class="pun">()</span><span class="pln">
    i </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">int</span><span
                class="pun">(</span><span class="pln">s</span><span class="pun">.</span><span
                class="pln">strip</span><span class="pun">())</span><span class="pln">
</span><span class="kwd">except</span><span class="pln"> </span><span class="typ">OSError</span><span
                class="pln"> </span><span class="kwd">as</span><span class="pln"> err</span><span
                class="pun">:</span><span class="pln">
    </span><span class="kwd">print</span><span class="pun">(</span><span class="str">"OS error: {0}"</span><span
                class="pun">.</span><span class="pln">format</span><span class="pun">(</span><span
                class="pln">err</span><span class="pun">))</span><span class="pln">
</span><span class="kwd">except</span><span class="pln"> </span><span class="typ">ValueError</span><span
                class="pun">:</span><span class="pln">
    </span><span class="kwd">print</span><span class="pun">(</span><span class="str">"Could not convert data to an integer."</span><span
                class="pun">)</span><span class="pln">
</span><span class="kwd">except</span><span class="pun">:</span><span class="pln">
    </span><span class="kwd">print</span><span class="pun">(</span><span class="str">"Unexpected error:"</span><span
                class="pun">,</span><span class="pln"> sys</span><span class="pun">.</span><span
                class="pln">exc_info</span><span class="pun">()[</span><span class="lit">0</span><span
                class="pun">])</span><span class="pln">
    </span><span class="kwd">raise</span></pre>
        <p>try except 语句还有一个可选的else子句，如果使用这个子句，那么必须放在所有的except子句之后。这个子句将在try子句没有发生任何异常的时候执行。例如:
        </p>
        <pre class="prettyprint prettyprinted" style=""><span class="kwd">for</span><span class="pln"> arg </span><span
                class="kwd">in</span><span class="pln"> sys</span><span class="pun">.</span><span
                class="pln">argv</span><span class="pun">[</span><span class="lit">1</span><span
                class="pun">:]:</span><span class="pln">
    </span><span class="kwd">try</span><span class="pun">:</span><span class="pln">
        f </span><span class="pun">=</span><span class="pln"> open</span><span class="pun">(</span><span
                class="pln">arg</span><span class="pun">,</span><span class="pln"> </span><span
                class="str">'r'</span><span class="pun">)</span><span class="pln">
    </span><span class="kwd">except</span><span class="pln"> </span><span class="typ">IOError</span><span
                class="pun">:</span><span class="pln">
        </span><span class="kwd">print</span><span class="pun">(</span><span class="str">'cannot open'</span><span
                class="pun">,</span><span class="pln"> arg</span><span class="pun">)</span><span class="pln">
    </span><span class="kwd">else</span><span class="pun">:</span><span class="pln">
        </span><span class="kwd">print</span><span class="pun">(</span><span class="pln">arg</span><span
                class="pun">,</span><span class="pln"> </span><span class="str">'has'</span><span
                class="pun">,</span><span class="pln"> len</span><span class="pun">(</span><span
                class="pln">f</span><span class="pun">.</span><span class="pln">readlines</span><span
                class="pun">()),</span><span class="pln"> </span><span class="str">'lines'</span><span
                class="pun">)</span><span class="pln">
        f</span><span class="pun">.</span><span class="pln">close</span><span class="pun">()</span></pre>
        <p>使用 else 子句比把所有的语句都放在 try 子句里面要好，这样可以避免一些意想不到的、而except又没有捕获的异常。</p>
        <p>异常处理并不仅仅处理那些直接发生在try子句中的异常，而且还能处理子句中调用的函数（甚至间接调用的函数）里抛出的异常。例如:</p>
        <pre class="prettyprint prettyprinted" style=""><span class="pun">&gt;&gt;&gt;</span><span
                class="pln"> </span><span class="kwd">def</span><span class="pln"> this_fails</span><span class="pun">():</span><span
                class="pln">
        x </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1</span><span
                class="pun">/</span><span class="lit">0</span><span class="pln">

</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> </span><span class="kwd">try</span><span
                class="pun">:</span><span class="pln">
        this_fails</span><span class="pun">()</span><span class="pln">
    </span><span class="kwd">except</span><span class="pln"> </span><span class="typ">ZeroDivisionError</span><span
                class="pln"> </span><span class="kwd">as</span><span class="pln"> err</span><span
                class="pun">:</span><span class="pln">
        </span><span class="kwd">print</span><span class="pun">(</span><span
                class="str">'Handling run-time error:'</span><span class="pun">,</span><span
                class="pln"> err</span><span class="pun">)</span><span class="pln">

</span><span class="typ">Handling</span><span class="pln"> run</span><span class="pun">-</span><span class="pln">time error</span><span
                class="pun">:</span><span class="pln"> </span><span class="kwd">int</span><span
                class="pln"> division </span><span class="kwd">or</span><span class="pln"> modulo </span><span
                class="kwd">by</span><span class="pln"> zero</span></pre>

        <h2>抛出异常</h2>
        <p>
            Python 使用 raise 语句抛出一个指定的异常。例如:</p>
        <pre class="prettyprint prettyprinted" style=""><span class="pun">&gt;&gt;&gt;</span><span
                class="pln"> </span><span class="kwd">raise</span><span class="pln"> </span><span
                class="typ">NameError</span><span class="pun">(</span><span class="str">'HiThere'</span><span
                class="pun">)</span><span class="pln">
</span><span class="typ">Traceback</span><span class="pln"> </span><span class="pun">(</span><span class="pln">most recent call </span><span
                class="kwd">last</span><span class="pun">):</span><span class="pln">
  </span><span class="typ">File</span><span class="pln"> </span><span class="str">"&lt;stdin&gt;"</span><span
                class="pun">,</span><span class="pln"> line </span><span class="lit">1</span><span
                class="pun">,</span><span class="pln"> </span><span class="kwd">in</span><span class="pln"> </span><span
                class="pun">?</span><span class="pln">
</span><span class="typ">NameError</span><span class="pun">:</span><span class="pln"> </span><span
                class="typ">HiThere</span></pre>
        <p>raise 唯一的一个参数指定了要被抛出的异常。它必须是一个异常的实例或者是异常的类（也就是 Exception 的子类）。</p>
        <p>如果你只想知道这是否抛出了一个异常，并不想去处理它，那么一个简单的 raise 语句就可以再次把它抛出。</p>
        <pre class="prettyprint prettyprinted" style=""><span class="pun">&gt;&gt;&gt;</span><span
                class="pln"> </span><span class="kwd">try</span><span class="pun">:</span><span class="pln">
        </span><span class="kwd">raise</span><span class="pln"> </span><span class="typ">NameError</span><span
                class="pun">(</span><span class="str">'HiThere'</span><span class="pun">)</span><span class="pln">
    </span><span class="kwd">except</span><span class="pln"> </span><span class="typ">NameError</span><span class="pun">:</span><span
                class="pln">
        </span><span class="kwd">print</span><span class="pun">(</span><span
                class="str">'An exception flew by!'</span><span class="pun">)</span><span class="pln">
        </span><span class="kwd">raise</span><span class="pln">

</span><span class="typ">An</span><span class="pln"> exception flew </span><span class="kwd">by</span><span class="pun">!</span><span
                class="pln">
</span><span class="typ">Traceback</span><span class="pln"> </span><span class="pun">(</span><span class="pln">most recent call </span><span
                class="kwd">last</span><span class="pun">):</span><span class="pln">
  </span><span class="typ">File</span><span class="pln"> </span><span class="str">"&lt;stdin&gt;"</span><span
                class="pun">,</span><span class="pln"> line </span><span class="lit">2</span><span
                class="pun">,</span><span class="pln"> </span><span class="kwd">in</span><span class="pln"> </span><span
                class="pun">?</span><span class="pln">
</span><span class="typ">NameError</span><span class="pun">:</span><span class="pln"> </span><span
                class="typ">HiThere</span></pre>

        <h2>用户自定义异常</h2>
        <p>你可以通过创建一个新的exception类来拥有自己的异常。异常应该继承自 Exception 类，或者直接继承，或者间接继承，例如:</p>
        <pre class="prettyprint prettyprinted" style=""><span class="pun">&gt;&gt;&gt;</span><span
                class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span
                class="typ">MyError</span><span class="pun">(</span><span class="typ">Exception</span><span class="pun">):</span><span
                class="pln">
        </span><span class="kwd">def</span><span class="pln"> __init__</span><span class="pun">(</span><span
                class="kwd">self</span><span class="pun">,</span><span class="pln"> value</span><span
                class="pun">):</span><span class="pln">
            </span><span class="kwd">self</span><span class="pun">.</span><span class="pln">value </span><span
                class="pun">=</span><span class="pln"> value
        </span><span class="kwd">def</span><span class="pln"> __str__</span><span class="pun">(</span><span class="kwd">self</span><span
                class="pun">):</span><span class="pln">
            </span><span class="kwd">return</span><span class="pln"> repr</span><span class="pun">(</span><span
                class="kwd">self</span><span class="pun">.</span><span class="pln">value</span><span
                class="pun">)</span><span class="pln">

</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> </span><span class="kwd">try</span><span
                class="pun">:</span><span class="pln">
        </span><span class="kwd">raise</span><span class="pln"> </span><span class="typ">MyError</span><span
                class="pun">(</span><span class="lit">2</span><span class="pun">*</span><span class="lit">2</span><span
                class="pun">)</span><span class="pln">
    </span><span class="kwd">except</span><span class="pln"> </span><span class="typ">MyError</span><span
                class="pln"> </span><span class="kwd">as</span><span class="pln"> e</span><span
                class="pun">:</span><span class="pln">
        </span><span class="kwd">print</span><span class="pun">(</span><span
                class="str">'My exception occurred, value:'</span><span class="pun">,</span><span
                class="pln"> e</span><span class="pun">.</span><span class="pln">value</span><span
                class="pun">)</span><span class="pln">

</span><span class="typ">My</span><span class="pln"> exception occurred</span><span class="pun">,</span><span
                class="pln"> value</span><span class="pun">:</span><span class="pln"> </span><span
                class="lit">4</span><span class="pln">
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> </span><span class="kwd">raise</span><span
                class="pln"> </span><span class="typ">MyError</span><span class="pun">(</span><span
                class="str">'oops!'</span><span class="pun">)</span><span class="pln">
</span><span class="typ">Traceback</span><span class="pln"> </span><span class="pun">(</span><span class="pln">most recent call </span><span
                class="kwd">last</span><span class="pun">):</span><span class="pln">
  </span><span class="typ">File</span><span class="pln"> </span><span class="str">"&lt;stdin&gt;"</span><span
                class="pun">,</span><span class="pln"> line </span><span class="lit">1</span><span
                class="pun">,</span><span class="pln"> </span><span class="kwd">in</span><span class="pln"> </span><span
                class="pun">?</span><span class="pln">
__main__</span><span class="pun">.</span><span class="typ">MyError</span><span class="pun">:</span><span
                class="pln"> </span><span class="str">'oops!'</span></pre>
        <p>在这个例子中，类 Exception 默认的 __init__() 被覆盖。</p>
        <p异常的类可以像其他的类一样做任何事情
                ，但是通常都会比较简单，只提供一些错误相关的属性，并且允许处理异常的代码方便的获取这些信息。
        < p="">
        <p>当创建一个模块有可能抛出多种不同的异常时，一种通常的做法是为这个包建立一个基础异常类，然后基于这个基础类为不同的错误情况创建不同的子类:</p>
        <pre class="prettyprint prettyprinted" style=""><span class="kwd">class</span><span class="pln"> </span><span
                class="typ">Error</span><span class="pun">(</span><span class="typ">Exception</span><span
                class="pun">):</span><span class="pln">
    </span><span class="str">"""Base class for exceptions in this module."""</span><span class="pln">
    </span><span class="kwd">pass</span><span class="pln">

</span><span class="kwd">class</span><span class="pln"> </span><span class="typ">InputError</span><span
                class="pun">(</span><span class="typ">Error</span><span class="pun">):</span><span class="pln">
    </span><span class="str">"""Exception raised for errors in the input.

    Attributes:
        expression -- input expression in which the error occurred
        message -- explanation of the error
    """</span><span class="pln">

    </span><span class="kwd">def</span><span class="pln"> __init__</span><span class="pun">(</span><span class="kwd">self</span><span
                class="pun">,</span><span class="pln"> expression</span><span class="pun">,</span><span class="pln"> message</span><span
                class="pun">):</span><span class="pln">
        </span><span class="kwd">self</span><span class="pun">.</span><span class="pln">expression </span><span
                class="pun">=</span><span class="pln"> expression
        </span><span class="kwd">self</span><span class="pun">.</span><span class="pln">message </span><span
                class="pun">=</span><span class="pln"> message

</span><span class="kwd">class</span><span class="pln"> </span><span class="typ">TransitionError</span><span
                class="pun">(</span><span class="typ">Error</span><span class="pun">):</span><span class="pln">
    </span><span class="str">"""Raised when an operation attempts a state transition that's not
    allowed.

    Attributes:
        previous -- state at beginning of transition
        next -- attempted new state
        message -- explanation of why the specific transition is not allowed
    """</span><span class="pln">

    </span><span class="kwd">def</span><span class="pln"> __init__</span><span class="pun">(</span><span class="kwd">self</span><span
                class="pun">,</span><span class="pln"> previous</span><span class="pun">,</span><span
                class="pln"> </span><span class="kwd">next</span><span class="pun">,</span><span
                class="pln"> message</span><span class="pun">):</span><span class="pln">
        </span><span class="kwd">self</span><span class="pun">.</span><span class="pln">previous </span><span
                class="pun">=</span><span class="pln"> previous
        </span><span class="kwd">self</span><span class="pun">.</span><span class="kwd">next</span><span
                class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span
                class="kwd">next</span><span class="pln">
        </span><span class="kwd">self</span><span class="pun">.</span><span class="pln">message </span><span
                class="pun">=</span><span class="pln"> message</span></pre>
        <p>大多数的异常的名字都以"Error"结尾，就跟标准的异常命名一样。</p>

        <h2>定义清理行为</h2>
        <p>try 语句还有另外一个可选的子句，它定义了无论在任何情况下都会执行的清理行为。 例如:</p>
        <pre class="prettyprint prettyprinted" style=""><span class="pun">&gt;&gt;&gt;</span><span
                class="pln"> </span><span class="kwd">try</span><span class="pun">:</span><span class="pln">
</span><span class="pun">...</span><span class="pln">     </span><span class="kwd">raise</span><span
                class="pln"> </span><span class="typ">KeyboardInterrupt</span><span class="pln">
</span><span class="pun">...</span><span class="pln"> </span><span class="kwd">finally</span><span
                class="pun">:</span><span class="pln">
</span><span class="pun">...</span><span class="pln">     </span><span class="kwd">print</span><span
                class="pun">(</span><span class="str">'Goodbye, world!'</span><span class="pun">)</span><span
                class="pln">
</span><span class="pun">...</span><span class="pln">
</span><span class="typ">Goodbye</span><span class="pun">,</span><span class="pln"> world</span><span
                class="pun">!</span><span class="pln">
</span><span class="typ">Traceback</span><span class="pln"> </span><span class="pun">(</span><span class="pln">most recent call </span><span
                class="kwd">last</span><span class="pun">):</span><span class="pln">
  </span><span class="typ">File</span><span class="pln"> </span><span class="str">"&lt;stdin&gt;"</span><span
                class="pun">,</span><span class="pln"> line </span><span class="lit">2</span><span
                class="pun">,</span><span class="pln"> </span><span class="kwd">in</span><span class="pln"> </span><span
                class="str">&lt;module&gt;</span><span class="pln">
</span><span class="typ">KeyboardInterrupt</span></pre>
        <p>以上例子不管 try 子句里面有没有发生异常，finally 子句都会执行。</p>
        <p>如果一个异常在 try 子句里（或者在 except 和 else 子句里）被抛出，而又没有任何的 except 把它截住，那么这个异常会在 finally 子句执行后再次被抛出。</p>
        <p>下面是一个更加复杂的例子（在同一个 try 语句里包含 except 和 finally 子句）:</p>
        <pre class="prettyprint prettyprinted" style=""><span class="pun">&gt;&gt;&gt;</span><span
                class="pln"> </span><span class="kwd">def</span><span class="pln"> divide</span><span
                class="pun">(</span><span class="pln">x</span><span class="pun">,</span><span class="pln"> y</span><span
                class="pun">):</span><span class="pln">
        </span><span class="kwd">try</span><span class="pun">:</span><span class="pln">
            result </span><span class="pun">=</span><span class="pln"> x </span><span class="pun">/</span><span
                class="pln"> y
        </span><span class="kwd">except</span><span class="pln"> </span><span class="typ">ZeroDivisionError</span><span
                class="pun">:</span><span class="pln">
            </span><span class="kwd">print</span><span class="pun">(</span><span
                class="str">"division by zero!"</span><span class="pun">)</span><span class="pln">
        </span><span class="kwd">else</span><span class="pun">:</span><span class="pln">
            </span><span class="kwd">print</span><span class="pun">(</span><span class="str">"result is"</span><span
                class="pun">,</span><span class="pln"> result</span><span class="pun">)</span><span class="pln">
        </span><span class="kwd">finally</span><span class="pun">:</span><span class="pln">
            </span><span class="kwd">print</span><span class="pun">(</span><span
                class="str">"executing finally clause"</span><span class="pun">)</span><span class="pln">

</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> divide</span><span class="pun">(</span><span class="lit">2</span><span
                class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">)</span><span
                class="pln">
result </span><span class="kwd">is</span><span class="pln"> </span><span class="lit">2.0</span><span class="pln">
executing </span><span class="kwd">finally</span><span class="pln"> clause
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> divide</span><span class="pun">(</span><span class="lit">2</span><span
                class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span
                class="pln">
division </span><span class="kwd">by</span><span class="pln"> zero</span><span class="pun">!</span><span class="pln">
executing </span><span class="kwd">finally</span><span class="pln"> clause
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> divide</span><span class="pun">(</span><span class="str">"2"</span><span
                class="pun">,</span><span class="pln"> </span><span class="str">"1"</span><span
                class="pun">)</span><span class="pln">
executing </span><span class="kwd">finally</span><span class="pln"> clause
</span><span class="typ">Traceback</span><span class="pln"> </span><span class="pun">(</span><span class="pln">most recent call </span><span
                class="kwd">last</span><span class="pun">):</span><span class="pln">
  </span><span class="typ">File</span><span class="pln"> </span><span class="str">"&lt;stdin&gt;"</span><span
                class="pun">,</span><span class="pln"> line </span><span class="lit">1</span><span
                class="pun">,</span><span class="pln"> </span><span class="kwd">in</span><span class="pln"> </span><span
                class="pun">?</span><span class="pln">
  </span><span class="typ">File</span><span class="pln"> </span><span class="str">"&lt;stdin&gt;"</span><span
                class="pun">,</span><span class="pln"> line </span><span class="lit">3</span><span
                class="pun">,</span><span class="pln"> </span><span class="kwd">in</span><span class="pln"> divide
</span><span class="typ">TypeError</span><span class="pun">:</span><span
                class="pln"> unsupported operand type</span><span class="pun">(</span><span class="pln">s</span><span
                class="pun">)</span><span class="pln"> </span><span class="kwd">for</span><span
                class="pln"> </span><span class="pun">/:</span><span class="pln"> </span><span
                class="str">'str'</span><span class="pln"> </span><span class="kwd">and</span><span class="pln"> </span><span
                class="str">'str'</span></pre>

        <h2>预定义的清理行为</h2>
        <p>一些对象定义了标准的清理行为，无论系统是否成功的使用了它，一旦不需要它了，那么这个标准的清理行为就会执行。</p>
        <p>这面这个例子展示了尝试打开一个文件，然后把内容打印到屏幕上:
        </p>
        <pre class="prettyprint prettyprinted" style=""><span class="kwd">for</span><span class="pln"> line </span><span
                class="kwd">in</span><span class="pln"> open</span><span class="pun">(</span><span class="str">"myfile.txt"</span><span
                class="pun">):</span><span class="pln">
    </span><span class="kwd">print</span><span class="pun">(</span><span class="pln">line</span><span
                class="pun">,</span><span class="pln"> </span><span class="kwd">end</span><span
                class="pun">=</span><span class="str">""</span><span class="pun">)</span></pre>
        <p>以上这段代码的问题是，当执行完毕后，文件会保持打开状态，并没有被关闭。</p>
        <p>关键词 with 语句就可以保证诸如文件之类的对象在使用完之后一定会正确的执行他的清理方法:</p>
        <pre class="prettyprint prettyprinted" style=""><span class="kwd">with</span><span class="pln"> open</span><span
                class="pun">(</span><span class="str">"myfile.txt"</span><span class="pun">)</span><span
                class="pln"> </span><span class="kwd">as</span><span class="pln"> f</span><span
                class="pun">:</span><span class="pln">
    </span><span class="kwd">for</span><span class="pln"> line </span><span class="kwd">in</span><span
                class="pln"> f</span><span class="pun">:</span><span class="pln">
        </span><span class="kwd">print</span><span class="pun">(</span><span class="pln">line</span><span
                class="pun">,</span><span class="pln"> </span><span class="kwd">end</span><span
                class="pun">=</span><span class="str">""</span><span class="pun">)</span></pre>
        <p>以上这段代码执行完毕后，就算在处理过程中出问题了，文件 f 总是会关闭。
        </p>

        </p异常的类可以像其他的类一样做任何事情，但是通常都会比较简单，只提供一些错误相关的属性，并且允许处理异常的代码方便的获取这些信息。<>
    </div>
</div>
</body>
</html>
